package ichubcontext

import (
	"gitee.com/ichub/goconfig/common/base/baseconfig"
	"gitee.com/ichub/goconfig/common/base/baseconfig/configdomain"
	"gitee.com/ichub/goconfig/common/base/baseconsts"
	"gitee.com/ichub/goconfig/common/base/basedto"
	"gitee.com/ichub/goconfig/common/base/encrypt"
	"gitee.com/ichub/goconfig/common/dbcontent/database"
	"gitee.com/ichub/goconfig/common/ichubcache"
	"gitee.com/ichub/goconfig/common/ichubconfig"
	"gitee.com/ichub/goconfig/common/ichubelastic"
	"gitee.com/ichub/goconfig/common/ichubredis"
	_ "github.com/gogf/gf/contrib/nosql/redis/v2"
	"github.com/gogf/gf/v2/database/gredis"
	"github.com/gogf/gf/v2/os/gsession"
	"time"

	"github.com/jinzhu/gorm"
	"github.com/sirupsen/logrus"
)

var IchubClient = NewIchubClientFactroy()
var gocache = ichubcache.NewCache()

type IchubClientFactroy struct {
	basedto.BaseEntitySingle

	ichubConfig *ichubconfig.IchubConfig

	dbDto    *baseconfig.DbClientDto
	dbClient *database.IchubDbClient

	esDto    *baseconfig.ElasticClientDto
	esclient *ichubelastic.ElasticClient

	redisDto    *baseconfig.RedisClientDto
	redisClient *ichubredis.IchubRedisClient
	gredis      *gredis.Redis

	mysqlDto    *baseconfig.DbClientDto
	mysqlClient *database.IchubDbClient
	dsDto       *baseconfig.DbClientDto
	dssqlClient *database.IchubDbClient

	natsDto *baseconfig.NatsClientDto

	SessionManager *gsession.Manager
}

func (this *IchubClientFactroy) Gredis() *gredis.Redis {
	return this.gredis
}

func (this *IchubClientFactroy) SetGredis(gredis *gredis.Redis) {
	this.gredis = gredis
}

func NewIchubClientFactroy() *IchubClientFactroy {
	var service = &IchubClientFactroy{
		ichubConfig: ichubconfig.FindBeanIchubConfig(),
	}
	service.InitProxy(service)

	return service
}
func (this *IchubClientFactroy) IchubConfig() *ichubconfig.IchubConfig {
	return this.ichubConfig
}

func (this *IchubClientFactroy) SetIchubConfig(ichubConfig *ichubconfig.IchubConfig) {
	this.ichubConfig = ichubConfig
}

func (this *IchubClientFactroy) DbClient() *database.IchubDbClient {
	return this.dbClient
}

// v	suite.dbinst = ichubcontext.IchubClient.IniDbClient().DbClient().Db
func (this *IchubClientFactroy) GetDB() *gorm.DB {
	return this.IniDbClient().dbClient.DbDebug()
}

func (this *IchubClientFactroy) SetDbClient(dbClient *database.IchubDbClient) {
	this.dbClient = dbClient
}

func (this *IchubClientFactroy) RedisClient() *ichubredis.IchubRedisClient {
	return this.redisClient
}

func (this *IchubClientFactroy) SetRedisClient(redisClient *ichubredis.IchubRedisClient) {
	this.redisClient = redisClient
}

func (this *IchubClientFactroy) Esclient() *ichubelastic.ElasticClient {
	return this.esclient
}

func (this *IchubClientFactroy) SetEsclient(esclient *ichubelastic.ElasticClient) {
	this.esclient = esclient
}

func (this *IchubClientFactroy) IniGredisClient() *IchubClientFactroy {
	if this.gredis == nil {
		this.redisDto = this.ichubConfig.ReadIchubRedis()
		var redisConfig = &gredis.Config{
			Address:     this.redisDto.Addr,
			Db:          this.redisDto.DB,
			Pass:        this.redisDto.Password,
			MinIdle:     10,  //			否	0	允许闲置的最小连接数
			MaxIdle:     100, //	否	10	允许闲置的最大连接数(0表示不限制)
			IdleTimeout: 90,  //
			MaxActive:   200, //	否	100
		}
		gredis.SetConfig(redisConfig, "cache")
		var err error
		this.gredis, err = gredis.New(redisConfig)
		if err != nil {
			logrus.Error(err)
			panic(err)
		}

	}
	return this
}
func (this *IchubClientFactroy) IniRedisClient() *IchubClientFactroy {
	if this.redisClient == nil {
		this.ichubConfig.Read()
		this.redisDto = this.ichubConfig.ReadIchubRedis()
		this.redisClient = ichubredis.NewIchubRedisClient()
		this.redisClient.SetRedisClientDto(this.redisDto)
		this.redisClient.Open()
	}
	return this
}
func (this *IchubClientFactroy) IniEsClient() *IchubClientFactroy {
	if this.esDto == nil {
		this.ichubConfig.Read()
		this.esDto = this.ichubConfig.ReadIchubEs()
		this.esclient = ichubelastic.New(this.esDto)
		this.esclient.Open()
	}
	return this
}

func (this *IchubClientFactroy) Ini() *IchubClientFactroy {
	this.ichubConfig.Read()
	this.IniRedisClient()
	this.IniDbClient()
	return this.IniEsClient()
}
func (this *IchubClientFactroy) IniMysqlClient() *IchubClientFactroy {
	if this.dbDto == nil {
		this.mysqlDto = this.ichubConfig.ReadIchubMysql()
		this.mysqlClient = database.FindDbClient(this.mysqlDto)

	}
	return this
}
func (this *IchubClientFactroy) IniDbClient() *IchubClientFactroy {
	if this.dbDto == nil {

		this.dbDto = this.ichubConfig.ReadIchubDb()
		this.dbClient = database.FindDbClient(this.dbDto)

	}
	return this
}
func (this *IchubClientFactroy) IniDsClient() *IchubClientFactroy {
	if this.dsDto == nil {
		this.dsDto = this.ichubConfig.ReadIchubDatasource()
		this.dbClient = database.FindDbClient(this.dsDto)
	}
	return this
}
func (this *IchubClientFactroy) GetIchubDbClient(dbtype string) *database.IchubDbClient {
	if dbtype == baseconsts.DB_TYPE_MYSQL {
		this.IniMysqlClient()
		return this.mysqlClient
	}
	if dbtype == "cockroach" {
		this.IniDsClient()
		return this.dssqlClient
	}

	this.IniDbClient()
	return this.dbClient
}

func (this *IchubClientFactroy) GetDbClientDto(dbtype string) *baseconfig.DbClientDto {
	if dbtype == baseconsts.DB_TYPE_MYSQL {
		return this.mysqlDto
	}
	if dbtype == "cockroach" {

		return this.dsDto
	}
	return this.dbDto
}
func (this *IchubClientFactroy) RegisterEncDec(encdec encrypt.IEncDec) *IchubClientFactroy {
	if this.ichubConfig != nil {
		this.ichubConfig.RegisterEncDec(encdec)
	}
	return this
}
func (this *IchubClientFactroy) GetNatsDto() *baseconfig.NatsClientDto {

	return this.ichubConfig.ReadNats()
}
func (this *IchubClientFactroy) IniSessionManager() *IchubClientFactroy {
	if this.SessionManager == nil {
		this.IniGredisClient()
		storage := gsession.NewStorageRedis(this.gredis)
		this.SessionManager = gsession.New(24*time.Hour, storage)

	}
	return this
}
func (this *IchubClientFactroy) MakeConfigAgg() *configdomain.ConfigAgg {
	var agg = configdomain.NewConfigAgg()
	//agg.Bypass=this.ichubConfig.ReadGateway().ByPass
	agg.Datasource = this.ichubConfig.ReadIchubDatasource()
	agg.DbClient = this.ichubConfig.ReadIchubDb()
	agg.WebClient = this.ichubConfig.ReadIchubWebClient()
	agg.WebServer = this.ichubConfig.ReadIchubWebServer()
	agg.NatsClient = this.ichubConfig.ReadNats()
	agg.RedisClient = this.ichubConfig.ReadIchubRedis()
	agg.ElasticClient = this.ichubConfig.ReadIchubEs()

	return agg
}
func (this *IchubClientFactroy) FindConfig(env string) *ichubconfig.IchubConfig {
	if c, ok := this.Gocache(env); ok {
		return c
	}
	var cfg *ichubconfig.IchubConfig
	switch env {
	case baseconsts.ENV_DEV:
		cfg = ichubconfig.NewIchubConfig().ReadDev()
	case baseconsts.ENV_TEST:
		cfg = ichubconfig.NewIchubConfig().ReadTest()
	case baseconsts.ENV_MASTER:
		cfg = ichubconfig.NewIchubConfig().ReadMaster()
	case baseconsts.ENV_RELEASE:
		cfg = ichubconfig.NewIchubConfig().ReadRelease()

	default:
		cfg = ichubconfig.NewIchubConfig().ReadDefault()
	}
	gocache.Set(env, cfg, time.Minute*60)
	return cfg
}
func (this *IchubClientFactroy) Gocache(env string) (*ichubconfig.IchubConfig, bool) {
	if c, ok := gocache.Get(env); c != nil && ok {
		return c.(*ichubconfig.IchubConfig), ok
	}

	//var c, ok = gocache.Get(baseconsts.ENV_DEFAULT)
	return nil, false
}
